#include "linked_list_msg.h"

void start_list (MessageList *list){

	list->first = (MessagePointer) malloc(sizeof(MessageCell));
	list->lastCellInOrder = list->first;
	//list->last = list->first;
	list->first->next = NULL;	

	list->lastCellInOrder->msg.hdr.id = 0;

}

int isEmpty (MessageList *list){

	return (list->first->next == NULL);

}

MessagePointer insert (char* msg_text, Header* hdr, MessageList* list, MessagePointer after){

    //Message* aux = getMessage (hdr->id, hdr->orig_id, list);
    
    //if (aux != NULL) return aux;
    MessagePointer aux = after->next;
	after->next = (MessagePointer) malloc (sizeof(MessageCell));

    after->next->next = aux;
	
	after->next->msg.hdr.id = hdr->id;
	after->next->msg.hdr.type = hdr->type;
	after->next->msg.hdr.tam_msg = hdr->tam_msg;
	strcpy(after->next->msg.hdr.orig_id, hdr->orig_id);
	strcpy(after->next->msg.hdr.dest_id, hdr->dest_id);
	
	strcpy(after->next->msg.msg_text, msg_text);
	
	return after->next;

}

int insertInOrder (char* msg_text, Header* hdr, MessageList* list, Header *lastHdr){
/*this function insert in order and return 1 if is completely in order, and 0 otherwise
  the parameter lastHdr is used to return the last header  */
  
    //printf("%d x %d\n", list->lastCellInOrder->msg.hdr.id + 1, hdr->id);
    
    if (list->lastCellInOrder->msg.hdr.id + 1 == hdr->id){ //If is the next after the last in order, insert
        
        MessagePointer aux = insert (msg_text, hdr, list, list->lastCellInOrder);        
        
        //verify if the included cell is the last in order        
        while(aux->next != NULL && (aux->next->msg.hdr.id == aux->msg.hdr.id + 1) ){
            aux = aux->next;
        }
        list->lastCellInOrder = aux;
        
        //printf("last: %d: %s from %s\n", list->lastCellInOrder->msg.hdr.id, list->lastCellInOrder->msg.msg_text, list->lastCellInOrder->msg.hdr.orig_id);
        *lastHdr = aux->msg.hdr;
        
        //return 1 if is completely in order (aux-> next is null)
        if (aux->next == NULL) return 1;       
    }
    else {
        lastHdr = &(list->lastCellInOrder->msg.hdr);
        MessagePointer aux = list->lastCellInOrder;
        while(aux != NULL){
            if (aux->msg.hdr.id == hdr->id) break;
            if (aux->next == NULL || aux->next->msg.hdr.id < hdr->id){
                insert (msg_text, hdr, list, aux);
                return 0;
            }
            aux = aux->next;
        }
        
    }
    return 0;
}

Message* getMessage (unsigned short int  id, char* orig_id, MessageList* list){
    MessagePointer aux;
    aux = list->first->next;
    //printf("%s, %d\n", orig_id, id);
        
    while(aux != NULL){
        //printf("%d\n", aux->msg.hdr.id);
        if (id == aux->msg.hdr.id && strcmp(orig_id, aux->msg.hdr.orig_id) == 0)
            return &aux->msg;
        aux = aux->next;
    }
    
    return NULL;
}

Message* getNextMessage (unsigned short int  id, char* orig_id, MessageList* list){
    MessagePointer aux;
    aux = list->first->next;
    
    while(aux != NULL){
        if (id == aux->msg.hdr.id && strcmp(orig_id, aux->msg.hdr.orig_id) == 0)
            return &aux->next->msg;
        aux = aux->next;
    }
    
    return NULL;
}

void printList (MessageList* list){
    MessagePointer aux;
    aux = list->first->next;
    printf("====================================================\n");
        
    while(aux != NULL){
        printf("%d: %s from %s\n", aux->msg.hdr.id, aux->msg.msg_text, aux->msg.hdr.orig_id);
        aux = aux->next;
    }
    
    printf("====================================================\n\n");
}

/*
Message* getLast(MessageList* list){
    return &list->last->msg;
}


int main (){
    MessageList lista;
    start_list(&lista);
    
    Header cabecalho;
    initialize_header (&cabecalho, 1, MSG, "192.168.0.1", "192.168.0.2");
    insert("teste1", &cabecalho, &lista);
    
    Message* test = getMessage (1, "192.168.0.1", &lista);
    if (test != NULL) printf("%s\n", test->msg_text);
    return 0;
}
*/
